import sys  # 导入sys模块，用于与Python解释器进行交互
import os  # 导入os模块，用于操作系统相关的功能
from datetime import datetime  # 从datetime模块导入datetime类，用于处理日期和时间

commodities = []  # 初始化一个空列表，用于存储商品信息

def print_separator():
    # 打印一个分隔符，长度为80个等号
    print("="*80)

def print_header(title):
    # 打印标题并在标题上下打印分隔符
    print_separator()
    # 居中打印标题，宽度为80
    print(title.center(80))
    print_separator()

def addc(proname, pronum, proprice, procount, description, production_date, shelf_life, supplier):
    # 定义一个函数用于添加商品，接收商品名称、编号、价格、数量、描述、生产日期、保质期和供应商信息作为参数
    commodity = {
        'proname': proname,
        'pronum': pronum,
        'proprice': proprice,
        'procount': procount,
        'description': description,
        'production_date': production_date,
        'shelf_life': shelf_life,
        'supplier': supplier
    }
    # 创建一个包含商品信息的字典
    commodities.append(commodity)
    # 将商品信息添加到commodities列表中
    return "添加成功"
    # 返回添加成功的信息

def findc():
    # 定义一个函数用于查找所有商品
    return commodities
    # 返回所有商品信息

def delc(pronum):
    # 定义一个函数用于删除商品，接收商品编号作为参数
    global commodities
    # 使用global关键字声明commodities是全局变量
    original_len = len(commodities)
    # 获取原始commodities列表的长度
    commodities = [commodity for commodity in commodities if commodity['pronum'] != pronum]
    # 使用列表推导式过滤出不包含指定商品编号的商品列表
    return "操作成功，已删除该商品" if len(commodities) < original_len else "你要删除的商品不存在"
    # 根据删除前后的列表长度判断是否删除成功，返回相应的信息

def updc(pronum, proprice, procount, description, production_date, shelf_life, supplier):
    # 定义一个函数用于更新商品信息，接收商品编号、价格、数量、描述、生产日期、保质期和供应商信息作为参数
    for commodity in commodities:
        # 遍历commodities列表中的每个商品
        if commodity['pronum'] == pronum:
            # 如果商品编号匹配
            commodity['proprice'] = proprice
            commodity['procount'] = procount
            commodity['description'] = description
            commodity['production_date'] = production_date
            commodity['shelf_life'] = shelf_life
            commodity['supplier'] = supplier
            # 更新商品信息
            return "操作成功，商品已修改"
            # 返回修改成功的信息
    return "你要修改的商品不存在"
    # 如果没有匹配的商品编号，返回商品不存在的信息

def findsum():
    # 定义一个函数用于计算每个商品的总价并返回商品名称、数量和总价的列表
    result = []
    # 初始化一个空列表用于存储结果
    for commodity in commodities:
        # 遍历commodities列表中的每个商品
        sum_price = commodity['proprice'] * commodity['procount']
        # 计算商品的总价
        result.append((commodity['proname'], commodity['procount'], sum_price))
        # 将商品名称、数量和总价作为元组添加到结果列表中
    return result
    # 返回结果列表

def find_by_id(pronum):
    # 定义一个函数用于根据商品编号查找商品，接收商品编号作为参数
    for commodity in commodities:
        # 遍历commodities列表中的每个商品
        if commodity['pronum'] == pronum:
            # 如果商品编号匹配，返回该商品
            return commodity
    return None
    # 如果没有匹配的商品编号，返回None

def import_commodities(filename):
    # 定义一个函数用于从文件导入商品信息，接收文件名作为参数
    try:
        with open(filename, 'r', encoding='utf-8') as file:
            # 以读模式打开文件并指定编码为UTF-8
            for line in file:
                # 逐行读取文件内容
                pronum, proname, proprice, procount, description, production_date, shelf_life, supplier = line.strip().split(',')
                # 分割每行数据并去除空格，按逗号分隔符拆分数据
                addc(proname, int(pronum), float(proprice), int(procount), description, production_date, shelf_life, supplier)
                # 调用addc函数将商品信息添加到commodities列表中
        return "导入成功"
        # 返回导入成功的信息
    except Exception as e:
        return f"导入失败: {e}"
        # 如果发生异常，返回导入失败的信息和异常信息

def export_commodities(filename):
    # 定义一个函数用于将商品信息导出到文件，接收文件名作为参数
    try:
        with open(filename, 'w', encoding='utf-8') as file:
            # 以写模式打开文件并指定编码为UTF-8
            for commodity in commodities:
                # 遍历commodities列表中的每个商品
                file.write(f"{commodity['pronum']},{commodity['proname']},{commodity['proprice']},{commodity['procount']},{commodity['description']},{commodity['production_date']},{commodity['shelf_life']},{commodity['supplier']}\n")
                # 将商品信息写入文件，每个属性之间用逗号分隔，行末尾添加换行符
        return "导出成功"
        # 返回导出成功的信息
    except Exception as e:
        return f"导出失败: {e}"
        # 如果发生异常，返回导出失败的信息和异常信息

def validate_input(prompt, expected_type):
    # 定义一个函数用于验证用户输入的类型，接收提示信息和期望的类型作为参数
    while True:
        try:
            if expected_type == int:
                return int(input(prompt).strip())
                # 如果期望类型是int，将用户输入转换为整数并返回
            elif expected_type == float:
                return float(input(prompt).strip())
                # 如果期望类型是float，将用户输入转换为浮点数并返回
            else:
                return input(prompt).strip()
                # 如果期望类型是str，直接返回用户输入的字符串
        except ValueError:
            print(f"无效输入，请输入一个{expected_type.__name__}类型的值。")
            # 如果输入类型不匹配，捕获ValueError异常并提示用户重新输入

def filter_by_supplier(supplier):
    # 定义一个函数用于按供应商筛选商品，接收供应商名称作为参数
    return [commodity for commodity in commodities if commodity['supplier'] == supplier]
    # 使用列表推导式返回供应商名称匹配的商品列表

def find_expired():
    # 定义一个函数用于查找已过期的商品
    today = datetime.now().strftime("%Y-%m-%d")
    # 获取当前日期并格式化为字符串
    return [commodity for commodity in commodities if commodity['production_date'] <= today]
    # 使用列表推导式返回生产日期早于或等于当前日期的商品列表

def print_commodities(commodities_list):
    # 定义一个函数用于打印商品信息，接收商品列表作为参数
    print("{:<10} {:<15} {:<10} {:<10} {:<15} {:<15} {:<10} {:<10}".format(
        "商品编号", "商品名称", "商品价格", "商品数量", "描述", "生产日期", "保质期", "供应商"
    ))
    # 打印表头，使用format方法格式化输出，每列设置宽度和对齐方式
    for commodity in commodities_list:
        # 遍历商品列表中的每个商品
        print("{:<10} {:<15} {:<10} {:<10} {:<15} {:<15} {:<10} {:<10}".format(
            commodity['pronum'], commodity['proname'], commodity['proprice'], commodity['procount'],
            commodity['description'], commodity['production_date'], commodity['shelf_life'],
            commodity['supplier']
        ))
        # 打印每个商品的信息，使用format方法格式化输出

def main():
    # 定义主函数，用于实现程序的主逻辑
    while True:
        print_header("超市管理系统")
        # 打印系统标题
        print("1. 添加货物".ljust(40), "2. 删除货物".ljust(40))
        # 打印菜单选项1和2，左对齐并设置宽度为40
        print("3. 修改货物".ljust(40), "4. 查看所有货物".ljust(40))
        # 打印菜单选项3和4，左对齐并设置宽度为40
        print("5. 查看特定货物".ljust(40), "6. 查看库存及总价".ljust(40))
        # 打印菜单选项5和6，左对齐并设置宽度为40
        print("7. 导入货物".ljust(40), "8. 导出货物".ljust(40))
        # 打印菜单选项7和8，左对齐并设置宽度为40
        print("9. 按供应商查看货物".ljust(40), "10. 查看已过期商品".ljust(40))
        # 打印菜单选项9和10，左对齐并设置宽度为40
        print("11. 退出".ljust(40))
        # 打印菜单选项11，左对齐并设置宽度为40
        print_separator()
        # 打印分隔符

        choice = validate_input("请选择操作: ", int)
        # 提示用户选择操作并验证输入类型为整数

        if choice == 1:
            # 如果用户选择添加货物
            print_header("添加货物")
            # 打印添加货物的标题
            pronum = validate_input("商品编号: ", int)
            # 提示用户输入商品编号并验证输入类型为整数
            proname = validate_input("商品名称: ", str)
            # 提示用户输入商品名称并验证输入类型为字符串
            proprice = validate_input("商品价格: ", float)
            # 提示用户输入商品价格并验证输入类型为浮点数
            procount = validate_input("商品数量: ", int)
            # 提示用户输入商品数量并验证输入类型为整数
            description = validate_input("描述: ", str)
            # 提示用户输入描述并验证输入类型为字符串
            production_date = validate_input("生产日期 (YYYY-MM-DD): ", str)
            # 提示用户输入生产日期并验证输入类型为字符串
            shelf_life = validate_input("保质期: ", str)
            # 提示用户输入保质期并验证输入类型为字符串
            supplier = validate_input("供应商: ", str)
            # 提示用户输入供应商并验证输入类型为字符串
            print(addc(proname, pronum, proprice, procount, description, production_date, shelf_life, supplier))
            # 调用addc函数添加商品并打印返回的信息

        elif choice == 2:
            # 如果用户选择删除货物
            print_header("删除货物")
            # 打印删除货物的标题
            pronum = validate_input("请输入要删除的商品编号: ", int)
            # 提示用户输入要删除的商品编号并验证输入类型为整数
            print(delc(pronum))
            # 调用delc函数删除商品并打印返回的信息

        elif choice == 3:
            # 如果用户选择修改货物
            print_header("修改货物")
            # 打印修改货物的标题
            pronum = validate_input("商品编号: ", int)
            # 提示用户输入商品编号并验证输入类型为整数
            proprice = validate_input("商品价格: ", float)
            # 提示用户输入商品价格并验证输入类型为浮点数
            procount = validate_input("商品数量: ", int)
            # 提示用户输入商品数量并验证输入类型为整数
            description = validate_input("描述: ", str)
            # 提示用户输入描述并验证输入类型为字符串
            production_date = validate_input("生产日期 (YYYY-MM-DD): ", str)
            # 提示用户输入生产日期并验证输入类型为字符串
            shelf_life = validate_input("保质期: ", str)
            # 提示用户输入保质期并验证输入类型为字符串
            supplier = validate_input("供应商: ", str)
            # 提示用户输入供应商并验证输入类型为字符串
            print(updc(pronum, proprice, procount, description, production_date, shelf_life, supplier))
            # 调用updc函数修改商品并打印返回的信息

        elif choice == 4:
            # 如果用户选择查看所有货物
            print_header("所有货物列表")
            # 打印所有货物列表的标题
            commodities_list = findc()
            # 调用findc函数获取所有商品列表
            print_commodities(commodities_list)
            # 调用print_commodities函数打印所有商品信息

        elif choice == 5:
            # 如果用户选择查看特定货物
            print_header("查看特定货物")
            # 打印查看特定货物的标题
            pronum = validate_input("请输入要查看的商品编号: ", int)
            # 提示用户输入要查看的商品编号并验证输入类型为整数
            commodity = find_by_id(pronum)
            # 调用find_by_id函数根据商品编号查找商品
            if commodity:
                # 如果找到商品
                print_commodities([commodity])
                # 打印该商品的信息
            else:
                print("未找到该商品")
                # 如果未找到商品，打印提示信息

        elif choice == 6:
            # 如果用户选择查看库存及总价
            print_header("库存及总价")
            # 打印库存及总价的标题
            result = findsum()
            # 调用findsum函数获取商品的名称、数量和总价
            for item in result:
                # 遍历结果列表中的每个项
                print(f"商品: {item[0]}, 商品库存: {item[1]}, 商品总价: {item[2]}")
                # 打印商品名称、数量和总价

        elif choice == 7:
            # 如果用户选择导入货物
            print_header("导入货物")
            # 打印导入货物的标题
            filename = os.path.join(os.path.dirname(__file__), "import_commodities.txt")
            # 获取导入文件的路径
            print(import_commodities(filename))
            # 调用import_commodities函数导入商品并打印返回的信息

        elif choice == 8:
            # 如果用户选择导出货物
            print_header("导出货物")
            # 打印导出货物的标题
            filename = os.path.join(os.path.dirname(__file__), "export_commodities.txt")
            # 获取导出文件的路径
            print(export_commodities(filename))
            # 调用export_commodities函数导出商品并打印返回的信息

        elif choice == 9:
            # 如果用户选择按供应商查看货物
            print_header("按供应商查看货物")
            # 打印按供应商查看货物的标题
            supplier = validate_input("请输入供应商名称: ", str)
            # 提示用户输入供应商名称并验证输入类型为字符串
            filtered_commodities = filter_by_supplier(supplier)
            # 调用filter_by_supplier函数按供应商筛选商品
            if filtered_commodities:
                # 如果找到符合条件的商品
                print_commodities(filtered_commodities)
                # 打印这些商品的信息
            else:
                print("未找到该供应商的商品")
                # 如果未找到符合条件的商品，打印提示信息

        elif choice == 10:
            # 如果用户选择查看已过期商品
            print_header("查看已过期商品")
            # 打印查看已过期商品的标题
            expired_commodities = find_expired()
            # 调用find_expired函数查找已过期的商品
            if expired_commodities:
                # 如果找到已过期的商品
                print_commodities(expired_commodities)
                # 打印这些商品的信息
            else:
                print("无已过期商品")
                # 如果未找到已过期的商品，打印提示信息

        elif choice == 11:
            # 如果用户选择退出系统
            print_header("退出系统")
            # 打印退出系统的标题
            print("感谢使用超市管理系统，再见！")
            # 打印退出系统的感谢信息
            break
            # 退出循环，结束程序

        else:
            print_header("无效的选择，请重新输入")
            # 如果用户输入无效的选择，提示用户重新输入

if __name__ == "__main__":
    main()
    # 如果该脚本是作为主程序运行，调用main函数
